﻿using Common.Framework.Core.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Common.Framework.Core.SqlSugar
{
    /// <summary>
    /// 定义实体仓储模型的数据标准操作
    /// </summary>
    /// <typeparam name="TEntity">实体类型</typeparam>
    public interface IBaseRepository<TEntity> where TEntity : BaseEntity, new()
    {
        /// <summary>
        /// 获取数据库链接(获取 SqlSugarClient 实例)
        /// </summary>
        /// <returns></returns>
        public ISqlSugarClient Connection();

        /// <summary>
        /// 获取: 雪花Id(唯一id)
        /// </summary>
        /// <returns></returns>
        public long GenerateId();

        #region 增
        /// <summary>
        /// 新增:操作成功返回实体对象.操作不成功则将实体对象的Id设置为0
        /// </summary>
        /// <param name="entity">需要操作的数据</param>
        /// <returns></returns>
        Task<TEntity> InsertAsync(TEntity entity);
        /// <summary>
        /// 新增 批量:默认判断Id是否已赋值,未赋值则会赋值
        /// </summary>
        /// <param name="entities">需要操作的数据</param>
        /// <returns></returns>
        Task<bool> InsertsAsync(List<TEntity> entities);
        /// <summary>
        ///  分表新增:操作成功返回实体对象.操作不成功则将实体对象的Id设置为0
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<TEntity> SplitTableInsertAsync(TEntity entity);
        /// <summary>
        ///  分表新增 批量:默认判断Id是否已赋值,未赋值则会赋值
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task<bool> SplitTableInsertAsync(List<TEntity> entities);


        #endregion

        #region 删
        /// <summary>
        /// 删除 逻辑:根据Id
        /// </summary>
        /// <param name="id">查询条件</param>
        /// <returns></returns>
        Task<bool> SoftDeleteByIdAsync(long id);
        /// <summary>
        /// 删除 逻辑: 根据id集合批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        Task<bool> SoftDeleteBatchByIdsAsync(List<long> ids);
        /// <summary>
        /// 删除 物理:根据Id
        /// </summary>
        /// <param name="id">查询条件</param>
        /// <returns></returns>
        Task<bool> RealDeleteByIdAsync(long id);
        #endregion

        #region 改
        /// <summary>
        /// 修改:根据Id更新实体对象,除id,CreateTime,DeleteFlag外全部更新.默认更新UpdateTime为当前时间.不会修改已逻辑删除的数据
        /// </summary>
        /// <param name="updateDataByColumns">需要操作的数据</param>
        /// <param name="id">查询条件</param>
        /// <returns></returns>
        Task<bool> UpdateByIdAsync(Expression<Func<TEntity, TEntity>> updateDataByColumns, long id);
        /// <summary>
        /// 修改:默认更新UpdateTime为当前时间.不会修改已逻辑删除的数据
        /// </summary>
        /// <param name="entity">需要操作的数据</param>
        /// <param name="id">查询条件</param>
        /// <returns></returns>
        Task<bool> UpdateByIdAsync(TEntity entity, long id);
        /// <summary>
        /// 修改:根据表达式更新记录.默认更新UpdateTime为当前时间.默认不会更新主键id.不会修改已逻辑删除的数据
        /// </summary>
        /// <param name="updateDataByColumns">需要操作的数据</param>
        /// <param name="whereExpression">查询条件</param>
        /// <returns></returns>
        Task<bool> UpdateByExpressionAsync(Expression<Func<TEntity, TEntity>> updateDataByColumns, Expression<Func<TEntity, bool>> whereExpression);
        /// <summary>
        /// 修改 批量:默认更新UpdateTime为当前时间.不会修改已逻辑删除的数据
        /// </summary>
        /// <param name="entities">需要操作的数据</param>
        /// <returns></returns>
        Task<bool> UpdatesByIdAsync(List<TEntity> entities);
        /// <summary>
        /// 修改 批量:根据表达式更新记录.默认更新UpdateTime为当前时间.不会修改已逻辑删除的数据
        /// </summary>
        /// <param name="entities">需要操作的数据</param>
        /// <param name="whereExpression">查询条件</param>
        /// <returns></returns>
        Task<bool> UpdatesByExpressionAsync(List<TEntity> entities, Expression<Func<TEntity, bool>> whereExpression);
        #endregion

        #region 查
        /// <summary>
        /// 查询:根据id 查询单条记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="selector">查询指定的栏位</param>
        /// <param name="noLock">是否允许脏读(true:允许;false:不允许)</param>
        /// <returns></returns>
        Task<TEntity> QueryByIdAsync(long id, Expression<Func<TEntity, TEntity>> selector = null, bool noLock = false);
        /// <summary>
        /// 查询:根据查询条件查询第一条记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <param name="selector">查询指定的栏位</param>
        /// <param name="orderByColumns">用来排序的字段</param>
        /// <param name="orderType">排序类型</param>
        /// <param name="noLock">是否允许脏读(true:允许;false:不允许)</param>
        /// <returns></returns>
        Task<TEntity> QueryByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, TEntity>> selector = null, Expression<Func<TEntity, object>> orderByColumns = null, OrderByType orderType = OrderByType.Desc, bool noLock = false);
        /// <summary>
        /// 查询 集合:根据条件查询所有记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <param name="selector">查询指定的栏位</param>
        /// <param name="orderByColumns">用来排序的字段.默认使用Id倒序排序</param>
        /// <param name="orderType">排序类型</param>
        /// <param name="noLock">是否允许脏读(true:允许;false:不允许)</param>
        /// <param name="distinct">是否去重(true:去重;false:不去重);注意:启用去重后orderBy将失效</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryListByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, TEntity>> selector = null, Expression<Func<TEntity, object>> orderByColumns = null, OrderByType orderType = OrderByType.Desc, bool noLock = false, bool distinct = false);
        /// <summary>
        /// 查询 分页集合:根据条件查询所有记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <param name="pageIndex">页码, 默认第一页</param>
        /// <param name="pageSize">条数,默认10条</param>
        /// <param name="selector">查询指定的栏位</param>
        /// <param name="orderByColumns">用来排序的字段.默认使用Id倒序排序</param>
        /// <param name="orderType">排序类型</param>
        /// <param name="noLock">是否允许脏读(true:允许;false:不允许)</param>
        /// <returns></returns>
        Task<PageResult<TEntity>> QueryPageListByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, int pageIndex, int pageSize, Expression<Func<TEntity, TEntity>> selector = null, Expression<Func<TEntity, object>> orderByColumns = null, OrderByType orderType = OrderByType.Desc, bool noLock = false);
        /// <summary>
        /// 查询 记录条数:根据条件查询所有记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <param name="noLock">是否允许脏读(true:允许;false:不允许)</param>
        /// <returns></returns>
        Task<int> CountByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, bool noLock = false);

        /// <summary>
        /// 分表查询:根据id,精准表名 查询单条记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="TableName"></param>
        /// <param name="selector"></param>
        /// <param name="noLock"></param>
        /// <returns></returns>
        Task<TEntity> SplitTableQueryByIdAsync(long id, string TableName, Expression<Func<TEntity, TEntity>> selector = null, bool noLock = false);
        /// <summary>
        /// 分表查询 集合:根据条件查询所有记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="TableNames"></param>
        /// <param name="BeginDate"></param>
        /// <param name="EndDate"></param>
        /// <param name="selector"></param>
        /// <param name="orderByColumns"></param>
        /// <param name="orderType"></param>
        /// <param name="noLock"></param>
        /// <param name="distinct"></param>
        /// <returns></returns>
        Task<List<TEntity>> SplitTableQueryListByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, string[] TableNames, DateTime? BeginDate = null, DateTime? EndDate = null, Expression<Func<TEntity, TEntity>> selector = null, Expression<Func<TEntity, object>> orderByColumns = null, OrderByType orderType = OrderByType.Desc, bool noLock = false, bool distinct = false);
        /// <summary>
        /// 分表查询 分页集合:根据条件查询所有记录.不会查询已逻辑删除的数据
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="TableNames"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="BeginDate"></param>
        /// <param name="EndDate"></param>
        /// <param name="selector"></param>
        /// <param name="orderByColumns"></param>
        /// <param name="orderType"></param>
        /// <param name="noLock"></param>
        /// <returns></returns>
        Task<PageResult<TEntity>> SplitTableQueryPageListByExpressionAsync(Expression<Func<TEntity, bool>> whereExpression, string[] TableNames, int pageIndex, int pageSize, DateTime? BeginDate = null, DateTime? EndDate = null, Expression<Func<TEntity, TEntity>> selector = null, Expression<Func<TEntity, object>> orderByColumns = null, OrderByType orderType = OrderByType.Desc, bool noLock = false);
        #endregion
    }
}